package com.hdd.biz.app.service.impl;

import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hdd.biz.account.entity.Account;
import com.hdd.biz.account.entity.AccountBill;
import com.hdd.biz.account.mapper.AccountBillMapper;
import com.hdd.biz.account.mapper.AccountMapper;
import com.hdd.biz.account.service.AccountBillService;
import com.hdd.biz.account.service.AccountService;
import com.hdd.biz.app.dto.*;
import com.hdd.biz.app.entity.AccountModel;
import com.hdd.biz.app.entity.WithdrawConfigureModel;
import com.hdd.biz.app.mapper.APPWithdrawMapper;
import com.hdd.biz.app.service.UserAccountService;
import com.hdd.biz.finance.entity.Paymet;
import com.hdd.biz.finance.entity.Withdraw;
import com.hdd.biz.finance.mapper.PaymetMapper;
import com.hdd.biz.member.entity.Member;
import com.hdd.biz.member.mapper.MemberMapper;
import com.hdd.biz.member.service.MemberService;
import com.hdd.biz.operate.entity.Dict;
import com.hdd.biz.operate.service.DictService;
import com.hdd.config.Constant;
import com.hdd.utils.wx.AliyunDysmsUtils;
import com.hdd.utils.wx.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@Slf4j
public class UserAccountServiceImpl implements UserAccountService {

    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private AccountBillMapper accountBillMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private MemberService memberService;
    @Autowired
    private APPWithdrawMapper appWithdrawMapper;
    @Autowired
    private AccountService accountService;
    @Autowired
    private AccountBillService accountBillService;
    @Autowired
    private DictService dictService;
    @Autowired
    private PaymetMapper paymetMapper;

    @Override
    public AppResponse withdraw(WithdrawRequest request) {
        AppResponse response = new AppResponse();
        //TODO 判断 账户  扣钱 冻结钱  生成日志 然后插入记录

        Account account = findAccount(request.getUserId());
        if(account==null){
            response.setMessage("账户不存在");
            response.setCode(-1000);
            return response;
        }

        Member member =  memberService.findMemberByUid(request.getUserId());
        if(member==null){
            response.setMessage("账户不存在");
            response.setCode(-1000);
            return response;
        }


        if(member.getDelFlag()>0){
            response.setMessage("帐号异常");
            response.setCode(-1000);
            return response;
        }


        BigDecimal amount = new BigDecimal(request.getAmount());
        if(account.getBalance().compareTo(amount)<0){
            response.setMessage("可用余额不足");
            response.setCode(-1000);
            return response;
        }


        if(!accountService.withdraw(account.getId(),request.getUserId(),request.getAmount(),request.getPlatform(),
                member.getAlipayAccount(),member.getRealName())){
            response.setMessage("提现失败");
            response.setCode(-1000);
            return response;
        };

        return response;
    }


    public Account findAccount(String userId){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id",userId);
        Account account =  accountMapper.selectOne(queryWrapper);
        return account;
    }


    @Override
    public AppResponse withdrawRecord(WithdrawRequest request) {
        AppResponse response = new AppResponse();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_id",request.getUserId());
        Page<Withdraw> pages = new Page<>(request.getPageNo(),request.getPageSize());
        wrapper.orderByDesc("create_time");
        IPage<Withdraw> mapIPage = appWithdrawMapper.selectPage(pages, wrapper);
        List<Withdraw> withdraws = mapIPage.getRecords();
        response.setItems(withdraws);
        return response;
    }


    @Override
    public AppResponse findAccount(AppRequest request) {
        AppResponse response = new AppResponse();
        AccountModel accountModel = new AccountModel();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_id",request.getUserId());

        Account account =  accountMapper.selectOne(wrapper);
        if(account==null){
            response.setCode(-1000);
            response.setMessage("账户不存在!");
            return response;
        }

        Member member = memberMapper.selectOne(wrapper);
        if(member==null){
            response.setCode(-1000);
            response.setMessage("用户不存在!");
            return response;
        }
        accountModel.setAccountId(account.getId());
        accountModel.setBalance(account.getBalance());
        accountModel.setAlipayAccount(member.getAlipayAccount());
        accountModel.setPhone(member.getPhone());
        accountModel.setName(member.getRealName());

        if(redisUtil.hasKey("paymentAmountSum:"+request.getUserId())){
            accountModel.setPaymentAmountSum(redisUtil.get("paymentAmountSum:"+request.getUserId()).toString());
          }else{
            accountModel.setPaymentAmountSum("0");
         }

        response.setItem(accountModel);
        return response;
    }

    @Override
    public AppResponse addAlipay(AliPayAccountRequest request) {
        AppResponse response = new AppResponse();
         Member member = new Member();
         member.setUserId(request.getUserId());
         member.setAlipayAccount(request.getAlipayAccount());
         member.setPhone(request.getPhone());
         member.setRealName(request.getName());
         //TODO 验证码校验
         if(memberMapper.insert(member)==0){
             response.setCode(-1000);
             response.setMessage("添加失败");
            return response;
         };

        return response;
    }

    @Override
    public AppResponse updateAlipay(AliPayAccountRequest request) {
        AppResponse response = new AppResponse();
        Member member = new Member();
        member.setUserId(request.getUserId());
        member.setAlipayAccount(request.getAlipayAccount());
        member.setPhone(request.getPhone());
        member.setRealName(request.getName());
        //TODO 验证码校验
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_id",request.getUserId());
        if(memberMapper.update(member,wrapper)==0){
            response.setCode(-1000);
            response.setMessage("修改失败");
            return response;
        };

        return response;
    }


    @Override
    public AppResponse balanceDetails(BillRequest request) {
        AppResponse response = new AppResponse();
        QueryWrapper<AccountBill> wrapper = new QueryWrapper();
        Page<AccountBill> pages = new Page<>(request.getPageNo(),request.getPageSize());
        wrapper.eq("account_id",request.getAccountId());
//        wrapper.ne("remarks","微信充值");
        wrapper.orderByDesc("id");
       // wrapper.orderByDesc("id");
        IPage<AccountBill> mapIPage = accountBillMapper.selectPage(pages, wrapper);
        List<AccountBill> agents = mapIPage.getRecords();
        response.setItems(agents);
        return response;
    }


    @Override
    public AppResponse getCode(AliPayAccountRequest request) {
        AppResponse response = new AppResponse();
        //TODO 验证码 REDIS
        if (request.getPhone().length() < 11) {
            response.setMessage("请填写正确的手机号");
            response.setCode(-1000);
            return response;
        }

        String regex = "^1[3|4|5|7|8][0-9]\\d{4,8}$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(request.getPhone());
        boolean isMatch = m.matches();
        if (!isMatch) {
            response.setMessage("请填写正确的手机号");
            response.setCode(-1000);
            return response;
        }

        StringBuilder str = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            int num = random.nextInt(10);
            str.append(num);
        }
        //获取当前登录人的信息
        Member member = memberService.findMemberByUid(request.getUserId());
        try {
            AliyunDysmsUtils.sendMessage(request.getPhone(), str.toString());
            //六位验证码，3分钟有效
            redisUtil.set("securityCode_" + member.getId() + "_" + request.getPhone(), str.toString(), 3 * 60);
        } catch (ClientException e) {
            e.printStackTrace();
            response.setMessage("验证码发送异常");
            response.setCode(-1000);
            return response;
        }
        response.setItem(str);
        return response;
    }

    @Override
    public AppResponse balanceDetails(BalanceDetailsRequest request) {
        AppResponse response = new AppResponse();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_id",request.getUserId());
        Account account =  accountMapper.selectOne(wrapper);
        if(account==null){
            response.setCode(-1000);
            response.setMessage("账户不存在");
            return response;
        }
        Page<AccountBill> pages = new Page<>(request.getPageNo(),request.getPageSize());
        wrapper.eq("account_id",account.getId());
        wrapper.orderByDesc("create_time");
        IPage<AccountBill> mapIPage = accountBillMapper.selectPage(pages, wrapper);
        List<AccountBill> accountBills = mapIPage.getRecords();
        response.setItems(accountBills);
        return response;
    }


    @Override
    public AppResponse rewardByWX(String userId, String worksUserId, String rewardAmount,String chargeAmount, String realityAmount,String rate,Integer payType) {

        log.info("微信打赏------余额操作");
        AppResponse response = new AppResponse();
        Account account = findAccount(userId);
        if(account==null){
            response.setMessage("账户不存在");
            response.setCode(-1000);
            return response;
        }

        Account worksAccount = findAccount(worksUserId);
        if(worksAccount==null){
            response.setMessage("账户不存在");
            response.setCode(-1000);
            return response;
        }

        BigDecimal amount = new BigDecimal(rewardAmount);

        //先充值
        accountService.increBlance(account.getId(),amount);
        accountBillService.addBill(account.getId(),amount,"I","微信充值", rate,realityAmount,chargeAmount,payType);

        //自己扣钱
        accountService.reduceBlance(account.getId(),amount);
        accountBillService.addBill(account.getId(),amount,"O","赞赏支出","0",rewardAmount,"0",payType);

        //对方加钱
        accountService.increaseIncome(worksAccount.getId(),amount);
        accountService.increBlance(worksAccount.getId(),amount);
        accountBillService.addBill(worksAccount.getId(),amount,"I","赞赏收入","0",rewardAmount,"0",payType);
        log.info("微信打赏------余额操作结束");
        return response;
    }




    @Override
    public AppResponse reward(String userId,String worksUserId,String rewardAmount) {
        AppResponse response = new AppResponse();
        Account account = findAccount(userId);
        if(account==null){
            response.setMessage("账户不存在");
            response.setCode(-1000);
            return response;
        }

        Account worksAccount = findAccount(worksUserId);
        if(worksAccount==null){
            response.setMessage("账户不存在");
            response.setCode(-1000);
            return response;
        }

        Member member =  memberService.findMemberByUid(userId);
        if(member==null){
            response.setMessage("账户不存在");
            response.setCode(-1000);
            return response;
        }

        BigDecimal amount = new BigDecimal(rewardAmount);
        if(account.getBalance().compareTo(amount)<0){
            response.setMessage("可用余额不足");
            response.setCode(-1001);
            return response;
        }

        //自己扣钱
        accountService.reduceBlance(account.getId(),amount);
        accountBillService.addBill(account.getId(),amount,"O","赞赏支出","0",rewardAmount,"0",0);
        //对方加钱
        accountService.increaseIncome(worksAccount.getId(),amount);
        accountService.increBlance(worksAccount.getId(),amount);
        accountBillService.addBill(worksAccount.getId(),amount,"I","赞赏收入","0",rewardAmount,"0",0);
        return response;
    }


    @Override
    public AppResponse withdrawConfigure(AppRequest request) {
        AppResponse response = new AppResponse();
        WithdrawConfigureModel configureModel = new WithdrawConfigureModel();
        Dict dict = dictService.findDictByName("WITHDRAWAL");
        if(dict==null){
            response.setCode(-1000);
            response.setMessage("读取提现配置失败");
            return response;
        }
        configureModel.setMin(dict.getDictValue());
        configureModel.setMax(dict.getDictValue2());
        response.setItem(configureModel);
        return response;
    }


    @Override
    public AppResponse getPaymentTips(AppRequest request) {
        AppResponse response = new AppResponse();
        if(redisUtil.hasKey("paymentTips:"+request.getUserId())){
            return response;
        }
        response.setCode(-1000);
        response.setMessage("暂无信息");
        return response;
    }


    @Override
    public AppResponse getPaymentTipsRest(AppRequest request) {
        AppResponse response = new AppResponse();
        redisUtil.del("paymentTips:"+request.getUserId());
        return response;
    }

    @Override
    public AppResponse raymentTipsRest(AppRequest request) {
        AppResponse response = new AppResponse();
        redisUtil.del("paymentAmountSum:"+request.getUserId());
        return response;
    }


    @Override
    public AppResponse rechargeRecord(WithdrawRequest request) {
        AppResponse response = new AppResponse();
        QueryWrapper<Paymet> wrapper = new QueryWrapper<>();
        Page<Paymet> pages = new Page<>(request.getPageNo(),request.getPageSize());
        wrapper.eq("user_id",request.getUserId());
        wrapper.orderByDesc("create_time");
        IPage<Paymet> mapIPage = paymetMapper.selectPage(pages, wrapper);
        response.setItems(mapIPage.getRecords());
        return response;
    }
}
